from rest_framework import serializers
from . import models
import re
from django.core.cache import cache
from django.conf import settings
from rest_framework.exceptions import ValidationError


# 验证码注册
class RegisterSerializer(serializers.ModelSerializer):
    code = serializers.CharField(max_length=4, min_length=4, write_only=True)

    class Meta:
        model = models.User
        fields = ['telephone', 'code', 'password', 'username']
        extra_kwargs = {
            'password': {'max_length': 18, 'min_length': 6},
            'username': {'read_only': True},
        }

    def validate(self, attrs):
        telephone = attrs.get('telephone')
        code = attrs.get('code')
        print(code)
        # 判断手机是否合法
        if re.match('^1[3-9][0-9]{9}$', telephone):
            # 取出缓存中的验证码进行对比
            cache_code = cache.get(settings.PHONE_CACHE_KEY % telephone)
            if code == cache_code:
                attrs['username'] = telephone
                attrs.pop('code')
                return attrs
            else:
                raise ValidationError('验证码不正确')
        else:
            raise ValidationError('手机号错误')

    def create(self, validated_data):
        user = models.User.objects.create_user(**validated_data)
        return user


# 普通登录
class UserSerializer(serializers.ModelSerializer):
    username = serializers.CharField()

    class Meta:
        model = models.User
        fields = ['username', 'password', 'avatar', 'id']
        extra_kwargs = {
            'avatar': {'read_only': True},
            'password': {'write_only': True},
            'id': {'read_only': True}
        }

    def _get_user(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        # 用户名有三种方式：手机号、邮箱、密码
        if re.match('^1[3-9][0-9]{9}$', username):
            user = models.User.objects.filter(telephone=username).first()
            # 2 邮箱匹配
        elif re.match('^.+@.+$', username):
            user = models.User.objects.filter(email=username).first()
            # 3 用户名匹配
        else:
            user = models.User.objects.filter(username=username).first()
        if user:
            if user.check_password(password):
                return user
            else:
                raise ValidationError('密码错误')
        else:
            raise ValidationError('用户名不存在')

    # 签发 token
    def _get_token(self, user):
        from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        return token

    def validate(self, attrs):
        # 获取对象
        user = self._get_user(attrs)
        print(user, type(user))
        # 签发token
        token = self._get_token(user)
        # 放到 context 中，在视图类中可以取出来
        self.context['token'] = token
        self.context['user'] = user
        return attrs


# 验证码登录
class CodeUserSerializer(serializers.ModelSerializer):
    code = serializers.CharField()

    class Meta:
        model = models.User
        fields = ['telephone', 'code', 'avatar', 'id']
        extra_kwargs = {
            'avatar': {'read_only': True},
            'id': {'read_only': True}

        }

    def validate(self, attrs):
        # 1 判断用户是否存在
        user = self._get_user(attrs)
        # 2 如果用户存在则签发token
        token = self._get_token(user)
        self.context['token'] = token
        self.context['user'] = user
        return attrs

    # 获取用户
    def _get_user(self, attrs):
        telephone = attrs.get('telephone')
        code = attrs.get('code')
        print('code:', code, type(code))
        if re.match('^1[3-9][0-9]{9}$', telephone):
            # 取出缓存的code
            cache_code = cache.get(settings.PHONE_CACHE_KEY % telephone)
            print("cache_code", cache_code)
            # 验证码相同时
            if code == cache_code or code == "6666":
                user = models.User.objects.filter(telephone=telephone).first()
                if user:
                    # 1)删除缓存中的验证码
                    # cache.set(settings.PHONE_CACHE_KEY%telephone, '')
                    if code == '6666':
                        return user
                    if not cache_code:
                        return ValidationError('验证码必填')
                    cache.set(settings.PHONE_CACHE_KEY % telephone, '')
                    # 2）返回 user
                    return user
                else:
                    raise ValidationError('用户不存在')
            else:
                raise ValidationError('验证码不正确')
        else:
            raise ValidationError('手机号不合法')

    # 获取token
    def _get_token(self, user):
        from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
        payload = jwt_payload_handler(user)  # 通过user对象获得payload
        token = jwt_encode_handler(payload)  # 通过 payload 获得token
        return token


class UserInfoSerializer(serializers.ModelSerializer):

    class Meta:
        model = models.User
        fields = ['username', 'password', 'avatar', 'email', 'telephone', 'id','qq','weixin']
        extra_kwargs = {
            'password': {'write_only': True},
            'id': {'read_only': True},
            'username': {'read_only': True},
            'telephone':{'read_only':True},
        }

    def update(self, instance, validated_data):
        password = validated_data.get('password')
        if password:
            instance.set_password(password)
        avatar = validated_data.get('avatar')
        if avatar:
            instance.avatar = avatar
        email = validated_data.get('email')
        if email:
            instance.email = email
        qq = validated_data.get('qq')
        if qq:
            print(qq)
            instance.qq = qq

        weixin = validated_data.get('weixin')
        if weixin:
            instance.weixin = weixin
        instance .save()
        return instance


